/*
*  LLNotifier.h
*  zMatch
*
*  Created by Alexander Trutchenko on 17/11/11.
*  Copyright 2011 League of Independent Developers. All rights reserved.
*
*/

#ifndef __LL_Notifier_h__
#define __LL_Notifier_h__

#include <map>
#include <list>
#include <string>


namespace lidlib {

class LLNotifierObserver;

////////////////////////////////////////////////////////
//
/** LLNotifier
* A class of instant notifications (pattern observer)
*  !!! Every listener must unregister itself on it's desruction 
*  !!! Listener must not send notifications in notification process function
*/
////////////////////////////////////////////////////////

class LLNotifier
{
typedef std::list<LLNotifierObserver*> LLObserverList;
typedef std::map<std::string, LLObserverList> LLObservers;
typedef std::list<std::pair<LLNotifierObserver*, std::string> > LLObserversListToRegisterUnregister;

private:
    LLObservers _observers;
//    bool _blocker;
	unsigned int _blockerCounter;
    LLObserversListToRegisterUnregister _listToRegisterUnregister;

private:
    static LLNotifier* _instance;

    LLNotifier():/*_blocker(false)*/ _blockerCounter(0) {};
    ~LLNotifier() {};

public:
        /** Remove instance */
    static void pvt_remove()
    {
        if (NULL != _instance)
        {
            delete _instance;
            _instance = NULL;
        }
    }

public:
        /** Register observer for notification named 'notificationName' */
    static void registerObserver(LLNotifierObserver* observer, const std::string& notificationName);
        /** Unregister observer for all notifications */
    static void unregisterObserver(LLNotifierObserver* observer);
        /** Every instance can send notification, not only observers */
    static void sendNotification(const std::string& notificationName, const void* pData);

private:

    void doRegisterObserver(LLNotifierObserver* observer, const std::string& notificationName);
    void doUnregisterObserver(LLNotifierObserver* observer);
    void doSendNotification(const std::string& notificationName, const void* pData);
};

} // namespace lidlib

#endif //__LL_Notifier_h__
